<?php
/**
 * 易优CMS
 * ============================================================================
 * 版权所有 2016-2028 海南赞赞网络科技有限公司，并保留所有权利。
 * 网站地址: http://www.eyoucms.com
 * ----------------------------------------------------------------------------
 * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
 * ============================================================================
 * Author: 陈风任 <491085389@qq.com>
 * Date: 2020-05-07
 */

namespace app\common\model;

use think\Db;
use think\Model;
use think\Cache;
use think\Config;

/**
 * 商城商品模块公共模型
 */
load_trait('controller/Jump');

class ShopGoods extends Model
{
    use \traits\controller\Jump;

    //初始化
    protected function initialize()
    {
        // 需要调用`Model`的`initialize`方法
        parent::initialize();
    }

    // 检测异常商品
    public function detectAbnormalGoods($goodsData = [], $return = false)
    {
        // 提取商品ID，查询商品是否已删除
        $product_ids = $this->getArraySpecifyColumn($goodsData, 'product_id');
        if (!empty($product_ids)) {
            $where = [
                'aid' => ['IN', $product_ids]
            ];
            $field = 'aid, status, is_del';
            $archives = Db::name('archives')->field($field)->where($where)->select();
            // 是否彻底删除
            if (empty($archives)) {
                if (empty($return)) {
                    $this->success('订单商品均已停售，不能再次购买', null, ['abnormal'=>1]);
                } else {
                    $result[] = [
                        'product_id' => ['IN', $product_ids],
                    ];
                    return $result;
                }
            }
            // 是否全部下架
            $isStatus = 0;
            foreach ($archives as $value) {
                if (!empty($value['status'])) $isStatus = 1;
            }
            if (empty($isStatus)) {
                if (empty($return)) {
                    $this->success('订单商品均已下架，不能再次购买', null, ['abnormal'=>1]);
                } else {
                    $result[] = [
                        'product_id' => ['IN', $product_ids],
                    ];
                    return $result;
                }
            }
            // 是否全部删除
            $isDel = 1;
            foreach ($archives as $value) {
                if (empty($value['is_del'])) $isDel = 0;
            }
            if (!empty($isDel)) {
                if (empty($return)) {
                    $this->success('订单商品均已停售，不能再次购买', null, ['abnormal'=>1]);
                } else {
                    $result[] = [
                        'product_id' => ['IN', $product_ids],
                    ];
                    return $result;
                }
            }
        }

        // 检测商品是否存在异常
        $abnormalGoodsID = $abnormalGoods = [];
        foreach ($goodsData as $key => $value) {
            // 查询条件
            $where = [
                'a.aid' => intval($value['product_id'])
            ];
            // 规格ID是否存在
            if (!empty($value['spec_value_id'])) {
                $productData = !empty($value['product_data']) ? unserialize($value['product_data']) : [];
                $goodsSpec = !empty($productData['product_spec']) ? htmlspecialchars_decode($productData['product_spec']) : '';
                $where['b.spec_value_id'] = strval($value['spec_value_id']);
                $field = 'a.aid, a.status, a.is_del, b.spec_stock';
                // 查询商品
                $archives = Db::name('archives')->alias('a')->join('__PRODUCT_SPEC_VALUE__ b', 'a.aid = b.aid', 'LEFT')->field($field)->where($where)->find();
                if (empty($archives)) {
                    $abnormalGoods[] = [
                        'goodsSpec' => $goodsSpec,
                        'abnormalMsg' => '商品已停售',
                        'goodsImg' => !empty($value['product_img']) ? $value['product_img'] : '',
                        'goodsName' => !empty($value['product_name']) ? $value['product_name'] : '',
                    ];
                    $abnormalGoodsID[] = [
                        'product_id' => intval($value['product_id']),
                        'spec_value_id' => $value['spec_value_id']
                    ];
                } else if (!empty($archives) && empty($archives['status'])) {
                    $abnormalGoods[] = [
                        'goodsSpec' => $goodsSpec,
                        'abnormalMsg' => '商品已下架',
                        'goodsImg' => !empty($value['product_img']) ? $value['product_img'] : '',
                        'goodsName' => !empty($value['product_name']) ? $value['product_name'] : '',
                    ];
                    $abnormalGoodsID[] = [
                        'product_id' => intval($value['product_id']),
                        'spec_value_id' => $value['spec_value_id']
                    ];
                } else if (!empty($archives) && empty($archives['spec_stock'])) {
                    $abnormalGoods[] = [
                        'goodsSpec' => $goodsSpec,
                        'abnormalMsg' => '商品已售罄',
                        'goodsImg' => !empty($value['product_img']) ? $value['product_img'] : '',
                        'goodsName' => !empty($value['product_name']) ? $value['product_name'] : '',
                    ];
                    $abnormalGoodsID[] = [
                        'product_id' => intval($value['product_id']),
                        'spec_value_id' => $value['spec_value_id']
                    ];
                } else if (!empty($archives) && !empty($archives['is_del'])) {
                    $abnormalGoods[] = [
                        'goodsSpec' => $goodsSpec,
                        'abnormalMsg' => '商品已停售',
                        'goodsImg' => !empty($value['product_img']) ? $value['product_img'] : '',
                        'goodsName' => !empty($value['product_name']) ? $value['product_name'] : '',
                    ];
                    $abnormalGoodsID[] = [
                        'product_id' => intval($value['product_id']),
                        'spec_value_id' => $value['spec_value_id']
                    ];
                }
            } else {
                $field = 'a.aid, a.status, a.stock_count, a.is_del';
                $archives = Db::name('archives')->alias('a')->field($field)->where($where)->find();
                if (empty($archives)) {
                    $abnormalGoods[] = [
                        'goodsSpec' => '',
                        'abnormalMsg' => '商品已停售',
                        'goodsImg' => !empty($value['product_img']) ? $value['product_img'] : '',
                        'goodsName' => !empty($value['product_name']) ? $value['product_name'] : '',
                    ];
                    $abnormalGoodsID[] = [
                        'product_id' => intval($value['product_id']),
                        'spec_value_id' => ''
                    ];
                } else if (!empty($archives) && empty($archives['status'])) {
                    $abnormalGoods[] = [
                        'goodsSpec' => '',
                        'abnormalMsg' => '商品已下架',
                        'goodsImg' => !empty($value['product_img']) ? $value['product_img'] : '',
                        'goodsName' => !empty($value['product_name']) ? $value['product_name'] : '',
                    ];
                    $abnormalGoodsID[] = [
                        'product_id' => intval($value['product_id']),
                        'spec_value_id' => ''
                    ];
                } else if (!empty($archives) && empty($archives['stock_count'])) {
                    $abnormalGoods[] = [
                        'goodsSpec' => '',
                        'abnormalMsg' => '商品已售罄',
                        'goodsImg' => !empty($value['product_img']) ? $value['product_img'] : '',
                        'goodsName' => !empty($value['product_name']) ? $value['product_name'] : '',
                    ];
                    $abnormalGoodsID[] = [
                        'product_id' => intval($value['product_id']),
                        'spec_value_id' => ''
                    ];
                } else if (!empty($archives) && !empty($archives['is_del'])) {
                    $abnormalGoods[] = [
                        'goodsSpec' => '',
                        'abnormalMsg' => '商品已停售',
                        'goodsImg' => !empty($value['product_img']) ? $value['product_img'] : '',
                        'goodsName' => !empty($value['product_name']) ? $value['product_name'] : '',
                    ];
                    $abnormalGoodsID[] = [
                        'product_id' => intval($value['product_id']),
                        'spec_value_id' => ''
                    ];
                }
            }
        }

        // 返回结果
        if (!empty($abnormalGoods)) {
            $resultData = [
                'abnormal' => 2,
                'abnormalGoods' => $abnormalGoods,
                'abnormalGoodsID' => $abnormalGoodsID
            ];
            if (empty($return)) {
                $this->success('以下商品存在异常，先将其他商品加入购物车？', null, $resultData);
            } else {
                return $abnormalGoodsID;
            }
        }
    }

    // 获取数据指定列，处理时执行去空、去重操作
    public function getArraySpecifyColumn($array = [], $field = '')
    {
        $result = [];
        if (!empty($array) && !empty($field)) {
            foreach ($array as $key => $value) {
                // 去空值、去重值
                if (!empty($value[$field]) && !in_array($value[$field], $result)) $result[] = $value[$field];
            }
        }
        return $result;
    }

    // 检测提交的商品是否可购买
    public function detectionGoods($post = [])
    {
        if (!empty($post['product_id'])) {
            if (!empty($post['spec_value_id'])) {
                $where = [
                    'aid' => $post['product_id'],
                    'spec_stock' => ['>', 0],
                    'spec_value_id' => $post['spec_value_id']
                ];
                $field = 'spec_stock';
                if (!empty($post['active_time_id'])) $field = 'seckill_stock';
                if (!empty($post['discount_active_id'])) $field = 'discount_stock';
                $specStock = Db::name('product_spec_value')->where($where)->getField($field);
                if (empty($specStock)) $this->error('商品已售罄！');
                if (intval($specStock) < intval($post['product_num'])) $this->error('商品最大库存：' . $specStock);
            } else {
                $where = [
                    'aid' => $post['product_id'],
                    'status' => 1,
                    'is_del' => 0,
                    'arcrank' => ['>=', 0]
                ];
                if (!empty($post['active_time_id'])) {
                    $stockCount = Db::name('sharp_goods')->where('aid', $post['product_id'])->getField('seckill_stock');
                } else if (!empty($post['discount_active_id'])) {
                    $stockCount = Db::name('discount_goods')->where('aid', $post['product_id'])->getField('discount_stock');
                } else {
                    $stockCount = Db::name('archives')->where($where)->getField('stock_count');
                }
                if (empty($stockCount)) $this->error('商品已售罄！');
                if (intval($stockCount) < intval($post['product_num'])) $this->error('商品最大库存：' . $stockCount);
            }
        }
    }

    // 查询商品信息列表(购物车商品 或 立即购买商品)
    public function getGoodsBuyList($cacheData = [], $usersID = 0)
    {
        $goodsList = [];
        if (!empty($cacheData)) {
            // 立即购买商品
            $where = [
                'a.aid' => !empty($cacheData['product_id']) ? intval($cacheData['product_id']) : 0,
            ];
            // 多规格条件
            if (!empty($cacheData['spec_value_id'])) $where['b.spec_value_id'] = $cacheData['spec_value_id'];
            // 查询字段
            $field = 'a.aid, a.typeid, a.title, a.litpic, a.users_price, a.stock_count, a.prom_type, a.attrlist_id, a.freight_fee_set, a.freight_fee_tpl, b.value_id, b.aid as product_id, b.spec_value_id, b.spec_price, b.spec_stock, c.template_id, c.status as template_status, c.template_ids, c.template_data, c.special_set, c.special_ids';
            // $field .= ',b.seckill_price, b.seckill_stock';
            // $field .= ',b.discount_price, b.discount_stock';
            $goodsList = Db::name('archives')->alias('a')->field($field)
                ->join('__PRODUCT_SPEC_VALUE__ b', 'a.aid = b.aid', 'LEFT')
                ->join('__SHOP_FREIGHT_TEMPLATE__ c', 'a.freight_fee_tpl = c.template_id', 'LEFT')
                ->where($where)
                ->limit(1)
                ->select();
            $goodsList[0]['product_num'] = $cacheData['product_num'];

            // if (isset($cacheData['active_time_id']) && !empty($cacheData['active_time_id'])) {
            //     $goodsList[0]['active_time_id'] = $cacheData['active_time_id'];
            //     //判断是否还在秒杀时间内
            //     $hour = date('H');
            //     $date = strtotime(date('Y-m-d'));
            //     $active_time = Db::name('sharp_active_time')
            //         ->alias('a')
            //         ->join('sharp_active b','a.active_id = b.active_id')
            //         ->where('b.active_date',$date)
            //         ->where('a.active_time',$hour)
            //         ->getField('active_time_id');
            //     if (empty($active_time) || $cacheData['active_time_id'] != $active_time){
            //         if (empty($goodsList)) $this->error('秒杀活动已结束!');
            //     }
            //     //判断该秒杀商品是多规格还是单规格
            //     $is_sku = Db::name('sharp_active_goods')
            //         ->alias('a')
            //         ->join('sharp_goods b','a.aid = b.aid')
            //         ->where('a.aid',$cacheData['product_id'])
            //         ->where('a.active_time_id',$cacheData['active_time_id'])
            //         ->getField('b.is_sku');
            //     $goodsList[0]['is_sku'] = $is_sku;
            //     if (empty($is_sku)){
            //         //单规格
            //         $active_goods = Db::name('sharp_goods')->where('aid',$cacheData['product_id'])->field('seckill_price,seckill_stock')->find();
            //         if (!empty($active_goods)){
            //             $goodsList[0]['users_price'] = $goodsList[0]['seckill_price'] = $active_goods['seckill_price'];
            //             $goodsList[0]['stock_count'] = $goodsList[0]['seckill_stock'] = $active_goods['seckill_stock'];
            //         }
            //     }
            // }
            // else if (isset($cacheData['discount_active_id']) && !empty($cacheData['discount_active_id'])) {
            //     $goodsList[0]['discount_active_id'] = $cacheData['discount_active_id'];
            //     $end_date = Db::name('discount_active')->where('active_id',$cacheData['discount_active_id'])->value('end_date');
            //     if ($end_date < getTime()){
            //         if (empty($goodsList)) $this->error('活动已结束!');
            //     }
            //     //判断该秒杀商品是多规格还是单规格
            //     $discount_goods = Db::name('discount_active_goods')
            //         ->alias('a')
            //         ->field('b.is_sku,b.discount_price,b.discount_stock')
            //         ->join('discount_goods b','a.aid = b.aid')
            //         ->where('a.aid',$cacheData['product_id'])
            //         ->where('a.active_id',$cacheData['discount_active_id'])
            //         ->find();
            //     $goodsList[0]['is_sku'] = $discount_goods['is_sku'];
            //     if (empty($discount_goods['is_sku'])){
            //         //单规格
            //         $goodsList[0]['users_price'] = $goodsList[0]['discount_price'] = $discount_goods['discount_price'];
            //         $goodsList[0]['stock_count'] = $goodsList[0]['discount_stock'] = $discount_goods['discount_stock'];
            //     }
            // }
        } else {
            // 购物车商品
            $where = [
                'a.selected' => 1,
                'a.users_id' => $usersID,
            ];
            // 查询字段
            $field = 'a.*, b.typeid, b.aid, b.title, b.litpic, b.users_price, b.stock_count, b.prom_type, b.attrlist_id, b.freight_fee_set, b.freight_fee_tpl, c.spec_price, c.spec_stock, c.value_id, d.template_id, d.status as template_status, d.template_ids, d.template_data, d.special_set, d.special_ids';
            $goodsList = Db::name('shop_cart')->alias('a')->field($field)
                ->join('__ARCHIVES__ b', 'a.product_id = b.aid', 'LEFT')
                ->join('__PRODUCT_SPEC_VALUE__ c', 'a.spec_value_id = c.spec_value_id and a.product_id = c.aid', 'LEFT')
                ->join('__SHOP_FREIGHT_TEMPLATE__ d', 'b.freight_fee_tpl = d.template_id', 'LEFT')
                ->where($where)
                ->select();
            if (empty($goodsList)) $this->error('003：您的购物车没有可购买的商品', url(''));
        }

        return $goodsList;
    }

    public function getGoodsShippingFee($goodsList = [], $address = [])
    {
        // 查询运费模板运费金额
        $shippingFee = 0;
        // 是否提示有所选地址不在这个商品配送区域内
        $allowSubmit = 1;
        // 商品选择的运费模板ID
        $templateID = [];
        // 商品是否可以配送
        foreach ($goodsList as $key => $value) {
            $value['special_msg'] = '';
            if (!empty($address['city']) && 2 === intval($value['freight_fee_set']) && !empty($value['template_id'])) {
                $specialIds = !empty($value['special_ids']) ? explode(',', trim($value['special_ids'], ',')) : [];
                // 查询收货地址是否在不配送区域内
                if (!empty($value['special_set']) && 1 === intval($value['special_set'])) {
                    if (in_array($address['city'], $specialIds)) {
                        $allowSubmit = 0;
                        $value['freight_fee_tpl'] = 0;
                        $value['special_msg'] = '[所选地址不在这个商品配送区域内]';
                    }
                }
                // 查询收货地址是否在只配送区域内
                else if (!empty($value['special_set']) && 2 === intval($value['special_set'])) {
                    if (!in_array($address['city'], $specialIds)) {
                        $allowSubmit = 0;
                        $value['freight_fee_tpl'] = 0;
                        $value['special_msg'] = '[所选地址不在这个商品配送区域内]';
                    }
                }
            }
            // 商品选择的运费模板ID
            if (!empty($value['freight_fee_tpl']) && 2 === intval($value['freight_fee_set'])) {
                if (!in_array($value['freight_fee_tpl'], $templateID)) array_push($templateID, $value['freight_fee_tpl']);
            }

            // 覆盖原数据
            $goodsList[$key] = $value;
        }

        // 商品运费模板查询处理
        if (!empty($templateID)) {
            $where = [
                'template_id' => ['IN', $templateID]
            ];
            $freightTemplate = Db::name('shop_freight_template')->where($where)->select();
            // 计算订单运费，多个模板则取最大运费值
            $freightFee = [];
            foreach ($freightTemplate as $key => $value) {
                $templateData = !empty($value['template_data']) ? unserialize($value['template_data']) : [];
                foreach ($templateData as $t_value) {
                    $freightIds = !empty($t_value['freight_ids']) ? explode(',', trim($t_value['freight_ids'], ',')) : [];
                    // 使用指定城市运费
                    if (in_array($address['city'], $freightIds)) {
                        $freightFee[$key] = $t_value['freight_fee'];
                        break;
                    }
                    // 使用全国统一运费
                    else {
                        $freightFee[$key] = $templateData[0]['freight_fee'];
                    }
                }
            }
            $shippingFee = !empty($freightFee) ? floatval(max($freightFee)) : 0;
        }

        // 返回数据
        return [
            'goodsList' => $goodsList,
            'shippingFee' => $shippingFee,
            'allowSubmit' => $allowSubmit
        ];
    }

    // 处理商品规格、会员折扣
    public function getGoodsHandleResult($goodsList = [], $usersDiscount = 1, $source = 'goodsBuy')
    {
        // 是否微信小程序访问
        $isWeixinApplets = isWeixinApplets();

        // 商品处理
        foreach ($goodsList as $key => $value) {
            // 未开启多规格则执行(未定义 或 未开启)
            // if (!isset($this->usersConfig['shop_open_spec']) || empty($this->usersConfig['shop_open_spec'])) {
            //     $value['spec_value_id'] = $value['spec_price'] = $value['spec_stock'] = 0;
            // }

            // 多规格商品则使用规格库存覆盖商品原库存，后续做真实计算
            if (!empty($value['spec_value_id'])) $value['stock_count'] = intval($value['spec_stock']);

            // 执行异常商品处理时跳过此判断
            if (!in_array($source, ['abnormal'])) {
                // 库存为0则清除这条数据并跳过本次循环以下操作
                if (empty($value['stock_count'])) {
                    unset($goodsList[$key]);
                    continue;
                }
            }

            // 多规格商品则使用规格价格覆盖商品原价格，后续做真实计算
            if (!empty($value['spec_value_id'])) $value['users_price'] = floatval($value['spec_price']);

            // 限时折扣商品多规格商品，则覆盖商品原来的价格 
            $value['discount_end_date'] = 0;
            if (!empty($value['discount_active_id'])) {
                if (empty($value['discount_price'])) {
                    $value['discount_price'] = Db::name('discount_goods')->where('aid', $value['product_id'])->value('discount_price');
                }
                $value['users_price'] = $value['spec_price'] = $value['discount_price'];
                $value['discount_end_date'] = Db::name('discount_active')->where('active_id', $value['discount_active_id'])->value('end_date');
            }

            // 商品原价
            $value['old_price'] = sprintf("%.2f", $value['users_price']);

            // 计算会员折扣价
            if (!empty($usersDiscount)) $value['users_price'] = floatval($value['users_price']) * floatval($usersDiscount);

            // 强制保留两位小数
            $value['users_price'] = sprintf("%.2f", floatval($value['users_price']));

            // 购买数量超过最大库存量则默认购买最大库存量
            if (intval($value['product_num']) > intval($value['stock_count'])) $value['product_num'] = intval($value['stock_count']);

            // 图片处理
            $value['litpic'] = !empty($isWeixinApplets) ? $this->get_default_pic($value['litpic'], true) : get_default_pic($value['litpic'], true);

            // 规格值组装处理
            $value['product_spec'] = [];
            if (!empty($value['spec_value_id'])) {
                $specValueID = explode('_', $value['spec_value_id']);
                if (!empty($specValueID)) {
                    $where = [
                        'aid' => $value['product_id'],
                        'spec_value_id' => ['IN', $specValueID]
                    ];
                    $ProductSpecData = Db::name("product_spec_data")->where($where)->field('spec_value')->select();
                    foreach ($ProductSpecData as $value_1) {
                        $value['product_spec'][] = !empty($value_1['spec_value']) ? $value_1['spec_value'] : '';
                    }
                }
            }
            $value['product_spec'] = !empty($value['product_spec']) ? implode('；', $value['product_spec']) : '';

            // 覆盖原商品数据
            $goodsList[$key] = $value;
        }

        return $goodsList;
    }

    // 商品数据整合处理
    public function getGoodsPriceHandle($goodsList = [], $globalParam = [])
    {
        // 商品数据处理
        $goodsArr = get_archives_data($goodsList, 'aid');
        foreach ($goodsList as $key => $value) {
            // 合计金额、合计数量计算
            if ($value['users_price'] >= 0 && !empty($value['product_num'])) {
                // 计算合计数量
                $globalParam['orderTotalNum'] += intval($value['product_num']);
                // 计算单品小计
                $subtotal = floatval($value['users_price']) * floatval($value['product_num']);
                $value['subtotal'] = sprintf("%.2f", floatval($subtotal));
                // 计算合计金额
                $globalParam['orderTotalAmount'] += floatval($subtotal);
                $globalParam['orderTotalAmount'] = sprintf("%.2f", floatval($globalParam['orderTotalAmount']));
            }
            // 判断订单类型，目前逻辑：一个订单中，只要存在一个普通产品(实物产品，需要发货物流)，则为普通订单
            // 0表示为普通订单，1表示为虚拟订单，虚拟订单无需发货物流，无需选择收货地址，无需计算运费
            if (empty($value['prom_type'])) $globalParam['promType'] = 0;
            // 商品详情链接
            $value['arcurl'] = urldecode(arcurl('home/Product/view', $goodsArr[$value['aid']]));

            // 覆盖原数据
            $goodsList[$key] = $value;
        }

        return [
            'goodsList' => $goodsList,
            'globalParam' => $globalParam
        ];
    }

    // 获取会员的商品优惠券
    public function getGoodsCoupon($goodsList = [], $usersID = 0)
    {
        // 处理商品信息
        $aids = $typeids = [];
        $typePrice = $aidPrice = $totolPrice = 0;
        foreach ($goodsList as $value) {
            if (!in_array($value['aid'], $aids)) {
                $aids[] = $value['aid'];
                $aidPrice += floatval($value['subtotal']);
            }
            if (!in_array($value['typeid'], $typeids)) {
                $typeids[] = $value['typeid'];
                $typePrice += floatval($value['subtotal']);
            }
            $totolPrice += floatval($value['subtotal']);
        }
        $aidPrice = !empty($aidPrice) ? sprintf("%.2f", floatval($aidPrice)) : 0;
        $typePrice = !empty($typePrice) ? sprintf("%.2f", floatval($typePrice)) : 0;
        $totolPrice = !empty($totolPrice) ? sprintf("%.2f", floatval($totolPrice)) : 0;

        // 查出顶级分类
        if (!empty($typeids)) {
            $typeData = Db::name('arctype')->where('id', 'IN', $typeids)->field('id, topid')->select();
            if (!empty($typeData)) {
                $typeids = [];
                foreach ($typeData as $value) {
                    if (0 == $value['topid'] && !in_array($value['id'], $typeids)) {
                        $typeids[] = $value['id'];
                    } else if (!empty($value['topid']) && !in_array($value['topid'], $typeids)) {
                        $typeids[] = $value['topid'];
                    }
                }
            }
        }

        // 时间戳
        $times = getTime();
        // 查询条件
        $where = [
            'a.users_id' => $usersID,
            'a.start_time' => ['<=', $times],
            'a.end_time' => ['>=', $times],
            'a.use_status' => 0,
            'b.coupon_id' => ['>', 1]
        ];
        // 查出全部的优惠券
        $goodsCoupon = Db::name('shop_coupon_use')
            ->alias('a')
            ->join('__SHOP_COUPON__ b', 'a.coupon_id = b.coupon_id', 'LEFT')
            ->where($where)
            ->getAllWithIndex('use_id');
        // 可用优惠券
        $useAllCoupon = $donUseAllCoupon = [];
        // 优惠券处理
        if (!empty($goodsCoupon)) {
            foreach ($goodsCoupon as $key => $value) {
                // 设置非默认使用优惠券
                $value['default'] = 0;
                // 是否属于满减券
                if (1 == $value['coupon_form']) $value['coupon_form_name'] = '满减券';

                // 优惠券有效期
                $value['end_time'] = !empty($value['end_time']) ? date('Y/m/d', $value['end_time']) : '';
                $value['start_time'] = !empty($value['start_time']) ? date('Y/m/d', $value['start_time']) : '';

                // 优惠券处理
                switch ($value['coupon_type']) {
                    case 2:
                        // 指定商品
                        $value['coupon_type_name'] = '指定商品';
                        if (!empty($value['product_id'])) {
                            $goodsArr = explode(",", $value['product_id']);
                            $in = 0;
                            foreach ($aids as $m) {
                                if (in_array($m, $goodsArr) && $aidPrice >= $value['conditions_use']) {
                                    // 此优惠券可用
                                    $in = 1;
                                    break;
                                } else {
                                    $donUseAllCoupon[] = $value;
                                }
                            }
                            if (!empty($in)) $useAllCoupon[] = $value;
                        }
                        break;
                    case 3:
                        // 指定分类
                        $value['coupon_type_name'] = '指定分类';
                        if (!empty($value['arctype_id'])) {
                            $arctypeArr = explode(",", $value['arctype_id']);
                            $in = 0;
                            foreach ($typeids as $m) {
                                if (in_array($m, $arctypeArr) && $typePrice >= $value['conditions_use']) {
                                    // 此优惠券可用
                                    $in = 1;
                                    break;
                                } else {
                                    $donUseAllCoupon[] = $value;
                                }
                            }
                            if (!empty($in)) $useAllCoupon[] = $value;
                        }
                        break;
                    default:
                        // 全部商品
                        $value['coupon_type_name'] = '全部商品';
                        if ($totolPrice >= $value['conditions_use']) {
                            $useAllCoupon[] = $value;
                        }  else {
                            $donUseAllCoupon[] = $value;
                        }
                        break;
                }
            }
        }
        // 设置优惠金额最大的优惠券为默认使用优惠券
        if (!empty($useAllCoupon)) {
            $priceSort = array_column($useAllCoupon, 'coupon_price');
            array_multisort($priceSort, SORT_DESC, $useAllCoupon);
            $useAllCoupon[0]['default'] = 1;
        }
        return [
            'useAllCoupon' => $useAllCoupon,
            'donUseAllCoupon' => $donUseAllCoupon
        ];
    }

    // 商品库存扣除
    public function goodsStockDeduct($upSpecValue = [])
    {
        if (!empty($upSpecValue)) {
            // 循环组装数据
            $arcData = $specData = [];
            foreach ($upSpecValue as $key => $value) {
                if (!empty($value['value_id'])) {
                    // 普通订单
                    $specData[] = [
                        'value_id' => $value['value_id'],
                        'spec_stock' => Db::raw('spec_stock-' . ($value['quantity'])),
                        'spec_sales_num' => Db::raw('spec_sales_num+' . ($value['quantity'])),
                    ];
                    $arcData[] = [
                        'aid' => $value['aid'],
                        'stock_count' => Db::raw('stock_count-' . ($value['quantity'])),
                        'sales_num'   => Db::raw('sales_num+' . ($value['quantity']))
                    ];
                } else {
                    // 普通订单
                    $arcData[] = [
                        'aid' => $value['aid'],
                        'stock_count' => Db::raw('stock_count-' . ($value['quantity'])),
                        'sales_num'   => Db::raw('sales_num+' . ($value['quantity']))
                    ];
                }
            }

            // 更新规格库存销量
            if (!empty($specData)) {
                $productSpecValueModel = new \app\user\model\ProductSpecValue();
                $productSpecValueModel->saveAll($specData);
            }

            // 更新商品库存销量
            if (!empty($arcData)) {
                $archivesModel = new \app\user\model\Archives();
                $archivesModel->saveAll($arcData);
            }
        }
    }

    // 商品库存恢复
    public function goodsStockRestore($order_id, $users_id = 0, $details_id = 0)
    {
        // 查询订单商品
        $where = [
            'a.users_id' => $users_id,
        ];
        if (is_array($order_id)) {
            $where['a.order_id'] = ['IN', get_arr_column($order_id, 'order_id')];
        } else {
            $where['a.order_id'] = $order_id;
        }
        if (!empty($details_id)) {
            $where['a.details_id'] = $details_id;
        }
        $field = 'a.product_id, b.value_id, a.spec_value_id, a.num as product_num';
        $orderDetails = Db::name('shop_order_details')
            ->alias('a')
            ->where($where)
            ->field($field)
            ->join('__PRODUCT_SPEC_VALUE__ b', 'a.product_id = b.aid && a.spec_value_id = b.spec_value_id', 'LEFT')
            ->select();
        if (!empty($orderDetails)) {
            // 循环组装数据
            $arcData = $specData = [];
            foreach ($orderDetails as $key => $value) {
                if (!empty($value['value_id'])) {
                    // 普通订单
                    $specData[] = [
                        'value_id' => $value['value_id'],
                        'spec_stock' => Db::raw('spec_stock+' . ($value['product_num'])),
                        'spec_sales_num' => Db::raw('spec_sales_num-' . ($value['product_num'])),
                    ];
                    $arcData[] = [
                        'aid' => $value['product_id'],
                        'stock_count' => Db::raw('stock_count+' . ($value['product_num'])),
                        'sales_num'   => Db::raw('sales_num-' . ($value['product_num']))
                    ];
                } else {
                    // 普通订单
                    $arcData[] = [
                        'aid' => $value['product_id'],
                        'stock_count' => Db::raw('stock_count+' . ($value['product_num'])),
                        'sales_num'   => Db::raw('sales_num-' . ($value['product_num']))
                    ];
                }
            }

            // 更新规格库存销量
            if (!empty($specData)) {
                $productSpecValueModel = new \app\user\model\ProductSpecValue();
                $productSpecValueModel->saveAll($specData);
                Db::name('product_spec_value')->where(['spec_sales_num'=>['lt',0]])->update(['spec_sales_num'=>0, 'update_time'=>getTime()]);
            }

            // 更新商品库存销量
            if (!empty($arcData)) {
                $archivesModel = new \app\user\model\Archives();
                $archivesModel->saveAll($arcData);
                Db::name('archives')->where(['sales_num'=>['lt',0]])->update(['sales_num'=>0, 'update_time'=>getTime()]);
            }
        }
    }
}